19.3 实战案例
🎯 本节目标
通过一个完整的数据分析案例,展示 DeepAnalyze 的端到端工作流程。
📊 案例:学生贷款风险分析
数据集描述
本案例使用 10 个学生贷款相关的数据文件:
| 文件名 | 描述 | 字段 |
|---|---|---|
person.csv | 借款人基本信息 | id, name, age, income |
male.xlsx | 性别信息 | id, gender |
enrolled.csv | 在读状态 | id, is_enrolled |
unemployed.xlsx | 失业状态 | id, is_unemployed |
filed_for_bankruptcy.csv | 破产记录 | id, has_bankruptcy |
no_payment_due.xlsx | 还款状态 | id, no_payment_due |
loan_amount.csv | 贷款金额 | id, amount |
interest_rate.xlsx | 利率信息 | id, rate |
loan_term.csv | 贷款期限 | id, term_months |
default_status.xlsx | 违约状态 | id, is_default |
分析目标
生成一份包含以下内容的深度分析报告:
- 数据概览和质量评估
- 违约率统计分析
- 风险因素识别
- 可视化展示
- 结论和建议
🚀 执行过程
Step 1: 启动 DeepAnalyze
python
from deepanalyze import DeepAnalyzeVLLM
# 初始化
deepanalyze = DeepAnalyzeVLLM(
checkpoint_path="RUC-DataLab/DeepAnalyze-8B"
)
# 设置工作目录
workspace = "/data/student_loans/"
# 分析请求
prompt = """
请分析工作目录中的学生贷款数据,生成一份完整的风险分析报告。
报告应包含:
1. 数据概览:数据质量、缺失值、基本统计
2. 违约率分析:整体违约率、不同群体违约率对比
3. 风险因素识别:找出与违约高度相关的因素
4. 可视化:关键发现的图表展示
5. 结论与建议:基于分析的风险管理建议
请确保代码可执行,图表保存到当前目录。
"""
# 执行分析
result = deepanalyze.generate(prompt, workspace)Step 2: Agent 推理过程
以下是 DeepAnalyze 的实际推理轨迹(简化版):
轮次 1: 数据探索
─────────────────
<Analyze>
首先,我需要了解工作目录中有哪些数据文件,
并加载它们进行初步探索。
</Analyze>
<Code>
import os
import pandas as pd
# 列出工作目录中的文件
files = os.listdir('.')
print("数据文件列表:")
for f in files:
print(f" - {f}")
</Code><Execute>
数据文件列表:
- person.csv
- male.xlsx
- enrolled.csv
- unemployed.xlsx
- filed_for_bankruptcy.csv
- no_payment_due.xlsx
- loan_amount.csv
- interest_rate.xlsx
- loan_term.csv
- default_status.xlsx
</Execute>轮次 2: 数据加载与合并
─────────────────────
<Understand>
工作目录包含 10 个数据文件,分为 CSV 和 Excel 格式。
我需要将它们全部加载并按 id 字段合并成一个完整的数据集。
</Understand>
<Code>
import pandas as pd
# 加载所有数据
person = pd.read_csv('person.csv')
male = pd.read_excel('male.xlsx')
enrolled = pd.read_csv('enrolled.csv')
unemployed = pd.read_excel('unemployed.xlsx')
bankruptcy = pd.read_csv('filed_for_bankruptcy.csv')
payment = pd.read_excel('no_payment_due.xlsx')
loan_amount = pd.read_csv('loan_amount.csv')
interest = pd.read_excel('interest_rate.xlsx')
term = pd.read_csv('loan_term.csv')
default_status = pd.read_excel('default_status.xlsx')
# 合并数据
dfs = [person, male, enrolled, unemployed, bankruptcy,
payment, loan_amount, interest, term, default_status]
df = dfs[0]
for d in dfs[1:]:
df = df.merge(d, on='id', how='left')
print(f"合并后数据集: {df.shape[0]} 行, {df.shape[1]} 列")
print("\n数据预览:")
print(df.head())
print("\n数据类型:")
print(df.dtypes)
</Code><Execute>
合并后数据集: 10000 行, 12 列
数据预览:
id name age income gender is_enrolled ...
0 1 Alice 25 45000 0 1 ...
1 2 Bob 32 62000 1 0 ...
...
数据类型:
id int64
name object
age int64
income float64
gender int64
is_enrolled int64
is_unemployed int64
has_bankruptcy int64
no_payment_due int64
amount float64
rate float64
term_months int64
is_default int64
dtype: object
</Execute>轮次 3: 数据质量评估
───────────────────
<Analyze>
现在我需要评估数据质量,检查缺失值和异常值。
</Analyze>
<Code>
# 缺失值检查
print("缺失值统计:")
print(df.isnull().sum())
# 基本统计
print("\n数值列统计:")
print(df.describe())
# 违约率
default_rate = df['is_default'].mean() * 100
print(f"\n整体违约率: {default_rate:.2f}%")
</Code><Execute>
缺失值统计:
id 0
name 0
age 0
income 23
gender 0
is_enrolled 0
is_unemployed 0
has_bankruptcy 0
no_payment_due 0
amount 5
rate 0
term_months 0
is_default 0
dtype: int64
数值列统计:
age income ... is_default
count 10000.000 9977.000000 ... 10000.000000
mean 35.234 52341.567890 ... 0.123400
std 12.456 28765.432100 ... 0.329012
min 18.000 12000.000000 ... 0.000000
25% 25.000 32000.000000 ... 0.000000
50% 33.000 48000.000000 ... 0.000000
75% 44.000 68000.000000 ... 0.000000
max 75.000 250000.000000 ... 1.000000
整体违约率: 12.34%
</Execute>轮次 4-6: 风险因素分析与可视化
─────────────────────────────
<Code>
import matplotlib.pyplot as plt
import seaborn as sns
# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei', 'Arial Unicode MS']
plt.rcParams['axes.unicode_minus'] = False
# 1. 不同群体的违约率对比
fig, axes = plt.subplots(2, 2, figsize=(14, 10))
# 失业状态 vs 违约
unemployed_default = df.groupby('is_unemployed')['is_default'].mean()
axes[0,0].bar(['在职', '失业'], unemployed_default.values * 100)
axes[0,0].set_title('就业状态与违约率')
axes[0,0].set_ylabel('违约率 (%)')
# 破产记录 vs 违约
bankruptcy_default = df.groupby('has_bankruptcy')['is_default'].mean()
axes[0,1].bar(['无破产记录', '有破产记录'], bankruptcy_default.values * 100)
axes[0,1].set_title('破产记录与违约率')
# 在读状态 vs 违约
enrolled_default = df.groupby('is_enrolled')['is_default'].mean()
axes[1,0].bar(['未在读', '在读'], enrolled_default.values * 100)
axes[1,0].set_title('在读状态与违约率')
axes[1,0].set_ylabel('违约率 (%)')
# 收入分布 vs 违约
df['income_group'] = pd.cut(df['income'], bins=[0, 30000, 50000, 80000, 300000],
labels=['低', '中低', '中高', '高'])
income_default = df.groupby('income_group')['is_default'].mean()
axes[1,1].bar(income_default.index.astype(str), income_default.values * 100)
axes[1,1].set_title('收入水平与违约率')
plt.tight_layout()
plt.savefig('risk_factors.png', dpi=150, bbox_inches='tight')
print("风险因素分析图已保存: risk_factors.png")
</Code><Execute>
风险因素分析图已保存: risk_factors.png
</Execute>轮次 7: 相关性分析
─────────────────
<Code>
# 计算各因素与违约的相关性
correlation_features = ['age', 'income', 'is_unemployed', 'has_bankruptcy',
'is_enrolled', 'no_payment_due', 'amount', 'rate', 'term_months']
correlations = {}
for feature in correlation_features:
if feature in df.columns:
corr = df[feature].corr(df['is_default'])
correlations[feature] = corr
# 按相关性排序
sorted_corr = sorted(correlations.items(), key=lambda x: abs(x[1]), reverse=True)
print("与违约的相关性排名:")
print("-" * 40)
for feature, corr in sorted_corr:
direction = "正相关" if corr > 0 else "负相关"
print(f"{feature:20s}: {corr:+.4f} ({direction})")
</Code><Execute>
与违约的相关性排名:
----------------------------------------
has_bankruptcy : +0.3521 (正相关)
is_unemployed : +0.2876 (正相关)
no_payment_due : -0.2234 (负相关)
income : -0.1987 (负相关)
rate : +0.1543 (正相关)
amount : +0.0987 (正相关)
term_months : +0.0654 (正相关)
is_enrolled : -0.0432 (负相关)
age : -0.0321 (负相关)
</Execute>轮次 8: 生成最终报告
───────────────────
<Answer>
# 学生贷款风险分析报告
## 摘要
本报告分析了 10,000 条学生贷款记录,整体违约率为 **12.34%**。
通过多维度分析,识别出了影响违约的关键风险因素。
---
## 1. 数据概览
### 1.1 数据集规模
- **总记录数**: 10,000 条
- **特征数量**: 12 个
- **违约样本**: 1,234 条 (12.34%)
### 1.2 数据质量
- 收入字段有 23 条缺失值 (0.23%)
- 贷款金额有 5 条缺失值 (0.05%)
- 整体数据质量良好
---
## 2. 违约率分析
### 2.1 整体违约率
**12.34%** 的借款人出现违约
### 2.2 分群违约率对比
| 群体 | 违约率 | 相对风险 |
|------|--------|---------|
| 有破产记录 | 38.5% | 3.1x |
| 失业状态 | 29.7% | 2.4x |
| 低收入群体 | 21.3% | 1.7x |
| 高利率贷款 | 18.9% | 1.5x |

---
## 3. 关键风险因素
### 3.1 相关性分析结果
按与违约相关性强度排序:
1. **破产记录** (r = +0.35): 最强风险信号
2. **失业状态** (r = +0.29): 还款能力直接影响
3. **还款记录** (r = -0.22): 良好记录降低风险
4. **收入水平** (r = -0.20): 高收入降低违约
### 3.2 风险因素解读
- **破产记录**是违约的最强预测因子
- **就业状态**显著影响还款能力
- **历史还款记录**是可靠的信用指标
---
## 4. 结论与建议
### 4.1 主要发现
1. 破产记录和失业状态是两个最重要的风险指标
2. 收入与违约呈负相关,高收入群体违约率更低
3. 良好的还款记录能有效降低违约风险
### 4.2 风险管理建议
1. **审批策略**
- 对有破产记录的申请人加强审核
- 建立收入验证机制
2. **贷后管理**
- 对失业借款人提供还款宽限期
- 建立早期预警系统
3. **产品设计**
- 考虑根据风险水平差异化定价
- 提供灵活还款选项
---
*报告生成时间: 2025-01-15*
*分析工具: DeepAnalyze v1.0*
</Answer>📊 生成的可视化

图:DeepAnalyze 生成的分析报告示例
📈 执行统计
| 指标 | 值 |
|---|---|
| 总轮次 | 8 轮 |
| 代码块数 | 7 个 |
| 执行时间 | ~180 秒 |
| 生成图表 | 2 个 |
| 报告字数 | ~800 字 |
🔍 与 LangGraph Agent 的对比
如果使用 LangGraph 实现相同的分析任务,代码结构会有很大不同:
LangGraph 版本(示意)
python
from langgraph.graph import StateGraph
from langgraph.prebuilt import create_react_agent
# 定义工具
@tool
def load_csv(filename: str) -> str:
"""加载 CSV 文件"""
df = pd.read_csv(filename)
return df.head().to_string()
@tool
def run_python(code: str) -> str:
"""执行 Python 代码"""
exec(code)
return "执行完成"
@tool
def save_plot(filename: str) -> str:
"""保存当前图表"""
plt.savefig(filename)
return f"已保存: {filename}"
# 创建 Agent
tools = [load_csv, run_python, save_plot]
agent = create_react_agent(llm, tools)
# 执行
result = agent.invoke({
"messages": [{"role": "user", "content": prompt}]
})关键差异
| 维度 | DeepAnalyze | LangGraph |
|---|---|---|
| 工具定义 | 隐式(代码执行) | 显式(@tool 装饰器) |
| 执行控制 | <Code> 标签 | tool_calls API |
| 状态管理 | 消息列表 | TypedDict State |
| 可扩展性 | 需重新训练 | 添加工具即可 |
| 专业性 | 数据科学专用 | 通用任务 |
💡 实践建议
何时使用 DeepAnalyze
✅ 适合场景:
- 标准化的数据分析流程
- 需要生成报告的任务
- 对数据隐私有要求(本地部署)
- 批量处理类似任务
❌ 不适合场景:
- 需要调用外部 API
- 需要与数据库交互
- 需要实时数据处理
- 需要多模态处理
优化技巧
清晰的 Prompt
- 明确列出分析目标
- 指定输出格式要求
- 提供必要的背景信息
数据准备
- 确保文件格式正确
- 提供数据字典说明
- 预处理明显的问题
结果验证
- 检查生成的代码逻辑
- 验证统计结果的合理性
- 审核可视化的准确性
接下来: 19.4 本章小结